#![allow(unused)]
//! Future的简化原理版Executor，可参考https://rust-lang.github.io/async-book/02_execution/04_executor.html说明
use std::{future::Future, pin::Pin, sync::{Arc, Mutex}, task::{Context, Poll, Waker}, thread, time::Duration };
use std::sync::mpsc::{SyncSender, Receiver, sync_channel};
use futures::future::BoxFuture;
use futures::task::{waker_ref, ArcWake};
use futures::FutureExt;

fn main() {
    let shared_state = Arc::new(Mutex::new(SharedState{completed: false, waker: None}));

    // 用另一个线程来模拟实际的IO、定时器等事件系统
    let thread_shared_state = Arc::clone(&shared_state);
    thread::spawn( move ||{
        thread::sleep(Duration::new(5, 0));
        let mut ss = thread_shared_state.lock().unwrap();
        ss.completed = true;
        if let Some(waker) = ss.waker.take() {
            waker.wake()
        }
    });

    let timer = TimerFuture{sn:"sd".to_owned(), shared_state};

    // 构建运行环境
    let (sender, receiver) = sync_channel(100);
    let executor = Executor{ready_queue: receiver};
    let spawner = Spawner{task_sender: sender};
    spawner.spawn(timer);
    drop(spawner);
    executor.run();
}

struct Spawner {
    task_sender: SyncSender<Arc<Task>>
}
impl Spawner {
    fn spawn(&self, future: impl Future<Output=u8> + 'static + Send) {
        let future = future.boxed();
        let task = Arc::new(Task {
            future: Mutex::new(Some(future)),
            task_sender: self.task_sender.clone(),
        });
        self.task_sender.send(task);
    }
}

struct Executor {
    ready_queue: Receiver<Arc<Task>>
}

struct Task {
    future: Mutex<Option<BoxFuture<'static, u8>>>,
    task_sender: SyncSender<Arc<Task>>
}

impl ArcWake for Task {
    fn wake_by_ref(arc_self: &Arc<Self>) {
        println!("timer future wake and send self to executor");
        arc_self.task_sender.send(arc_self.clone());
    }
}

impl Executor {
    fn run(&self) {
        println!("executor start");
        while let Ok(task) = self.ready_queue.recv() {
            println!("executor recv one task");
            let mut future_slot = task.future.lock().unwrap();
            if let Some(mut future) = future_slot.take() {
                let waker = waker_ref(&task);
                let mut context = Context::from_waker(&*waker);
                if let Poll::Pending = future.as_mut().poll(&mut context) {
                    *future_slot = Some(future)
                }
            }
        }
        println!("taskSender drop and executor exit");
    }
}

struct SharedState {
    completed: bool,
    waker: Option<Waker>
}

struct TimerFuture {
    sn: String,
    shared_state: Arc<Mutex<SharedState>>
}

impl Future for TimerFuture {
    type Output = u8;
    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
        let mut shared_state = self.shared_state.lock().unwrap();
        if shared_state.completed {
            println!("timer future is ready");
            Poll::Ready(88)
        } else {
            shared_state.waker = Some(cx.waker().clone());
            println!("timer future is pending");
            Poll::Pending
        }
    }
}









